package com.harboursoftware.xstorage.web;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.LongRange;

/**
 * 
 * @author Simon Leung
 * @since 0.1
 */
abstract class PostPolicyCondition<T> {
    private String key;

    public PostPolicyCondition(String key) {
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    /**
     * 判断value是否符合条件限制
     * 
     * @param value
     * @return
     */
    public abstract boolean matchs(T value);

    public static PostPolicyCondition<String> createStartsWithCondition(String key, String prefix) {
        return new StartsWithCondition(key, prefix);
    }

    /**
     * 如果values包含“,”号
     * 
     * @param key
     * @param value
     * @return
     */
    public static PostPolicyCondition<String> createExactMatchesCondition(String key, String values) {
        String[] valueArray = StringUtils.split(values, ",");
        return new ExactMatchesCondition(key, valueArray);
    }

    public static PostPolicyCondition<Long> createSpecifyingRangesCondition(String key, long lower, long upper) {
        return new SpecifyingRangesCondition(key, lower, upper);
    }

    private static class StartsWithCondition extends PostPolicyCondition<String> {
        private String prefix;

        public StartsWithCondition(String key, String prefix) {
            super(key);
            this.prefix = prefix;
        }

        @Override
        public boolean matchs(String value) {
            if (prefix.length() == 0) {
                return true;
            }
            return getKey().startsWith(prefix);
        }
    }

    private static class ExactMatchesCondition extends PostPolicyCondition<String> {
        private String[] values;

        public ExactMatchesCondition(String key, String[] values) {
            super(key);
            this.values = values;
        }

        @Override
        public boolean matchs(String value) {
            return ArrayUtils.contains(values, value);
        }
    }

    private static class SpecifyingRangesCondition extends PostPolicyCondition<Long> {
        private LongRange range;

        public SpecifyingRangesCondition(String key, long lower, long upper) {
            super(key);
            range = new LongRange(lower, upper);
        }

        @Override
        public boolean matchs(Long value) {
            return range.containsLong(value);
        }
    }
}
